﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DotaHelp.Models;
using System.Text.RegularExpressions;
using DotaHelp.Helpers;
using System.Collections.Concurrent;

namespace DotaHelp.Controllers
{

    
    public class CommentsController : Controller
    {
        DotaModel model = new DotaModel();

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            model.Dispose();
            
        }

        public ActionResult Chat()
        {
            return View();
        }

        public ActionResult InnerChat()
        {
            
            return PartialView(new Comment()
            {
                Url = "/Chat",
                Author = Request.GetUserName()
            });
        }

        static ConcurrentDictionary<string, DateTime> activeUsers = new ConcurrentDictionary<string, DateTime>();


        [HttpPost]        
        public ActionResult ChatMessages()
        {
            activeUsers.AddOrUpdate(ControllerContext.HttpContext.PrepareUserName(Request.GetUserName()), DateTime.Now, (a, b) => DateTime.Now);
            var from = DateTime.Now.AddMinutes(-5);
            ViewBag.ActiveUsers = activeUsers.AsEnumerable().Where(a => a.Value > from).OrderByDescending(a => a.Value).Select(a => a.Key);

            return PartialView("ChatMessages", model.Comments.Where(c => c.IsDeleted == false).Where(a=>a.Url == "/Chat").OrderByDescending(a => a.PostDate).Take(20));
        }
        
        public ActionResult List(int? page, string orderBy)
        {
            var comments = model.Comments.Where(c => !c.IsDeleted);
            return View(comments.ByPage(page, orderBy, p => p.Raiting, p => p.PostDate, ViewData, HttpContext));
        }

        [ChildActionOnly]
        public ActionResult ListForUrl(string url, string title, string image, int? top)
        {
            if (top == null)
            {
                ViewBag.Comments = model.Comments.Where(c => c.Url == url).Where(c => !c.IsDeleted).OrderBy(c => c.PostDate).ToArray();
            }
            else
            {
                ViewBag.Comments = model.Comments.Where(c => c.Url == url).Where(c => !c.IsDeleted).OrderByDescending(c => c.PostDate).Take(top.Value).ToArray();
            }

            ViewBag.Title = title;
            ViewBag.Image = image;
            ViewBag.IsOrdered = top == null;

            return PartialView(new Comment()
            {
                Url = url,
                Author = Request.GetUserName()
            });
        }

        [HttpPost]
        [Authorize]
        public void RemoveChatComment(int id)
        {
            var c = model.Comments.First(m => m.Id == id);
            c.IsDeleted = true;
            model.UpdateFieldLogs.AddObject(new UpdateFieldLog() { Date = DateTime.Now, RowId = id, LastValue = c.Text, NewValue = "удален " + User.Identity.Name, TableName = "Comments", UserName = ControllerContext.HttpContext.PrepareUserName(Request.GetUserName()), FieldName = "IsDeleted" });
            model.SaveChanges();
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult AddToChat(Comment comment, int? secretCode)
        {
            Response.SaveUserName(comment.Author);

            if (secretCode == null)
            {
                return Content("<font color='red'>Необходимо ввести текущее число</font>");
            }

            var date = DateTime.UtcNow.NowByAstana();
            var valid = date.AddDays(-1).Day == secretCode ||
                date.Day == secretCode ||
                date.AddDays(+1).Day == secretCode;

            if (!valid)
            {
                return Content("<font color='red'>Введено неверное число</font>");
            }

            comment.PostDate = DateTime.UtcNow.NowByAstana();
            comment.IpAddress = Request.ServerVariables["REMOTE_ADDR"];
            comment.Author = ControllerContext.HttpContext.PrepareUserName(comment.Author);

            //bool ignore = model.IgnoreComments.ToArray().Any(regex => Regex.IsMatch(comment.Text, regex.Regex, RegexOptions.IgnoreCase));
            //comment.IsDeleted = ignore || code2 == 0 || code2 % 17 != 0;
            comment.Author = comment.Author; /*(comment.IsDeleted ? "spamdetected:" : "") +
                (ignore ? "by ignore" : "")
                + comment.Author;*/

            model.Comments.AddObject(comment);
            model.SaveChanges();

            return ChatMessages();
        } 
      
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Add(Comment comment, int? secretCode)
        {           
            Response.SaveUserName(comment.Author);

            if (secretCode == null)
            {
                return Content("<font color='red'>Необходимо ввести текущее число</font>");
            }

            var date = DateTime.UtcNow.NowByAstana();
            var valid = date.AddDays(-1).Day == secretCode ||
                date.Day == secretCode ||
                date.AddDays(+1).Day == secretCode;

            if (!valid)
            {
                return Content("<font color='red'>Введено неверное число</font>");
            }

            comment.PostDate = DateTime.UtcNow.NowByAstana();
            comment.IpAddress = Request.ServerVariables["REMOTE_ADDR"];
            comment.Author = ControllerContext.HttpContext.PrepareUserName(comment.Author);
            
            //bool ignore = model.IgnoreComments.ToArray().Any(regex => Regex.IsMatch(comment.Text, regex.Regex, RegexOptions.IgnoreCase));
            //comment.IsDeleted = ignore || code2 == 0 || code2 % 17 != 0;
            comment.Author = comment.Author; /*(comment.IsDeleted ? "spamdetected:" : "") +
                (ignore ? "by ignore" : "")
                + comment.Author;*/

            model.Comments.AddObject(comment);
            model.SaveChanges();
            return PartialView("One", comment);  
        } 
        

        [Authorize(Roles = "Admin")]
        public void Delete(int id)
        {
            var comment = model.Comments.First(c => c.Id == id);
            comment.IsDeleted = true;
            model.SaveChanges();
        }

        [ChildActionOnly]
        public ActionResult LastNews()
        {
            var comments = from c in model.Comments
                where c.Url == "/GuestBook" && c.Text.StartsWith("News:") 
                orderby c.PostDate descending
                select c;

            return PartialView(comments.Take(3));
        }

        [ChildActionOnly]
        public ActionResult One(Comment comment)
        {
            return View(comment);
        }

        [ChildActionOnly]
        public ActionResult CompactListForUrl(string url, Comment[] comments)
        {
            ViewBag.Comments = comments ?? new Comment[0];
            ViewBag.Group = url.Replace("/", "_"); 

            return PartialView(new Comment()
            {
                Url = url,
                Author = Request.GetUserName()
            });
        }

		[ChildActionOnly]
		public ActionResult CompactListForUrl2(string url)
		{			
			ViewBag.Comments = model.Comments.Where(c => !c.IsDeleted && c.Url == url).OrderBy(c => c.PostDate).ToArray();
			ViewBag.Group = url.Replace("/", "_");

			return PartialView("CompactListForUrl", new Comment()
			{
				Url = url,
				Author = Request.GetUserName()
			});
		}

        [Authorize(Roles = "Admin")]
        public ActionResult DeletedList(int? page, string orderBy)
        {
            ViewBag.Ignore = model.IgnoreComments.ToArray();

            var comments = model.Comments.Where(c => c.IsDeleted);
            return View(comments.ByPage(page, orderBy, null, p => p.PostDate, ViewData, HttpContext));
        }

        [Authorize(Roles = "Admin")]
        public ActionResult Restore(int id)
        {
            var comment = model.Comments.First(c => c.Id == id);
            comment.IsDeleted = false;
            comment.Author = comment.Author.StartsWith("spamdetected:") ? comment.Author.Remove(0, "spamdetected:".Length) : comment.Author;
            comment.Author = comment.Author.StartsWith("by ignore") ? comment.Author.Remove(0, "by ignore".Length) : comment.Author;
            model.SaveChanges();

            return RedirectToAction("DeletedList");
        }

        [Authorize(Roles = "Admin")]
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult AddIgnore(string word)
        {
            model.IgnoreComments.AddObject(new IgnoreComment() { Regex = word });
            model.SaveChanges();

            return RedirectToAction("DeletedList");
        }

        [ChildActionOnly]
        public string Rating(int id, bool isPlus)
        {
            var c = model.Comments.First(p => p.Id == id);
            c.Raiting += isPlus ? 1 : -1;
            model.SaveChanges();
            return c.Raiting.ToString();
        } 
    }
}
